package com.ciaojian.client.controller;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.ciaojian.client.service.DyRecordServiceImpl;
import com.ciaojian.client.service.OrderServiceImpl;
import com.ciaojian.client.service.UserServiceImpl;
import com.ciaojian.client.util.*;
import com.ciaojian.client.util.FileUtil;
import com.ciaojian.core.enums.business.OrderOrderTypeEnum;
import com.ciaojian.core.enums.business.OrderStatusEnum;
import com.ciaojian.core.mapper.DyRecordMapper;
import com.ciaojian.core.mapper.UserHairperiodMapper;
import com.ciaojian.core.mapper.UserMapper;
import com.ciaojian.core.model.*;
import com.ciaojian.core.model.dto.OrderDTO;
import com.ciaojian.core.model.vo.UserPortrait;
import com.ciaojian.core.util.*;
import com.ciaojian.miniapp.api.WxMiniAppApi;
import com.ciaojian.miniapp.model.request.QRCodeUnlimited;
import io.swagger.annotations.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.io.*;
import java.net.URL;
import java.net.URLConnection;
import java.util.Base64;
import java.util.Calendar;
import java.util.Date;
import java.util.concurrent.TimeUnit;

/**
 * @author Atlakyn
 */
@Api(tags = "用户模块: 用户相关")
@RestController
@RequestMapping("/user")
public class UserController {
    @Resource
    private OrderServiceImpl orderService;
    @Resource
    private UserServiceImpl userService;
    @Resource
    private DyRecordServiceImpl<DyRecordMapper, DyRecord> dyRecordService;
    @Resource
    private UserMapper userMapper;
    @Resource
    private UserHairperiodMapper userHairperiodMapper;
    @Autowired
    private FileProperties properties;
    @Autowired
    private RedisTemplate redisTemplate;

    @ApiOperation("用户是不是第一次消费(包含购买剪发服务及会员权益)")
    @GetMapping("/first-consume")
    public Result firstConsume(Integer userId) {
        return Result.ok(orderService.countNumberOfCompleteByUserId(userId) == 0);
    }

    @ApiOperation("获取用户当天是否有购买抖音产品")
    @GetMapping("/is-douyin")
    public Result isDouyin(Integer userId) {
        Integer count = dyRecordService.lambdaQuery()
                .eq(DyRecord::getUserId, userId)
                .eq(DyRecord::getUsed, Boolean.FALSE)
                .between(DyRecord::getCreateTime, DateUtil.beginOfDay(new Date()), DateUtil.endOfDay(new Date()))
                .count();
        return Result.ok(count > 0);
    }

    @ApiOperation("用户是否为新用户")
    @GetMapping("/is-new")
    public Result isNew(Integer userId) {
        // 判断标准是 没有排队中/服务中/待付款/待回调/已支付/已完成/的订单
        Integer count = orderService.lambdaQuery()
                .eq(Order::getUserId, userId)
                .eq(Order::getOrderType, OrderOrderTypeEnum.NORMAL)
                .in(Order::getStatus, OrderStatusEnum.waiting,
                        OrderStatusEnum.servicing,
                        OrderStatusEnum.wait_pay,
                        OrderStatusEnum.wait_notify,
                        OrderStatusEnum.paid,
                        OrderStatusEnum.complete,
                        OrderStatusEnum.rebates)
                .count();
        return Result.ok(count == 0);
    }

    @GetMapping("/openid")
    public Result getByOpenId(String openId) {
        LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(User::getOpenid, openId);
        return Result.ok(new User().selectCount(lambdaQueryWrapper) > 0);
    }

    @ApiResponses({
            @ApiResponse(code = 200, message = "success", response = OrderDTO.class)
    })
    @ApiOperation("已服务的发型师")
    @GetMapping("/worker/serviced")
    public Result serviceWorker(Integer userId) {
        return Result.ok(orderService.getBaseMapper().findByUserId(userId));
    }

    @ApiOperation("根据ID查询用户")
    @GetMapping("/{id}")
    public Result get(@PathVariable Integer id) {
        User one = userService.lambdaQuery()
                .eq(User::getId, id).one();
        return Result.ok(one);
    }


    @ApiOperation("获取用户的小程序码")
    @GetMapping("/qr-code")
    public Result getQRCode(String scene) {
        QRCodeUnlimited qrCodeUnlimited = QRCodeUnlimited.builder().build()
                .setScene(scene)
                .setPage("pages/myshare/isshare/isshare")
                .setWidth(300);
        try {
            return Result.ok(WxMiniAppApi.getUnlimited(qrCodeUnlimited));
        } catch (IOException e) {
            e.printStackTrace();
            LogUtil.writeErrorLog(e, e.getMessage());
            return Result.error("生成失败");
        }
    }


    @ApiOperation("获取用户的小程序码, 带跳转")
    @GetMapping("/qr-code/v2")
    public Result getQRCode(String scene, String page) {
        QRCodeUnlimited qrCodeUnlimited = QRCodeUnlimited.builder().build()
                .setScene(scene)
                .setPage(page)
                .setWidth(300);
        try {
            return Result.ok(WxMiniAppApi.getUnlimited(qrCodeUnlimited));
        } catch (IOException e) {
            e.printStackTrace();
            LogUtil.writeErrorLog(e, e.getMessage());
            return Result.error("生成失败");
        }
    }

    @ApiOperation("地铁扫码用户")
    @GetMapping("/metro_qr")
    public Result getQRCode(String storeType, Integer storeId) {
        if (ObjectUtil.isNull(storeType) && !"metro".equals(storeType)){
            //不是通过地铁扫码进来的
            return Result.error("非地铁扫码");
        }

        Store store = new Store().selectById(storeId);
        if (store.getType()!=5){
            return Result.error("非地铁扫码");
        }
        store.setQrCodenum(store.getQrCodenum()+1);
        store.updateById();
        return Result.ok();
    }

    @ApiOperation("是否剪过发")
    @GetMapping("/is-normal")
    public Result isNormal(Integer userId) {
        // 判断标准是 没有排队中/服务中/待付款/待回调/已支付/已完成/的订单
        Integer count = orderService.lambdaQuery()
                .eq(Order::getUserId, userId)
                .eq(Order::getOrderType, OrderOrderTypeEnum.NORMAL)
                .in(Order::getStatus,
                        OrderStatusEnum.paid,
                        OrderStatusEnum.complete,
                        OrderStatusEnum.rebates)
                .count();
        return Result.ok(count == 0);
    }


    @ApiModelProperty("获取用户头像信息")
    @PostMapping("/userPortrait")
    public Result userPortrait(@RequestBody UserPortrait userPortrait) {

        User user = userMapper.selectById(userPortrait.getId());
        File file = null;
        String suffix = "";
        if (userPortrait.getIsUrl()==0) {
            if (ObjectUtil.isNotNull(userPortrait.getAvatarUrl())) {
                BASE64DecodedMultipartFile base64DecodedMultipartFile = null;
                base64DecodedMultipartFile = (BASE64DecodedMultipartFile) Base64StrToImage.base64MutipartFile(userPortrait.getAvatarUrl());
                try {

                    FileUtil.checkSize(properties.getMaxSize(), base64DecodedMultipartFile.getSize());
                    suffix = FileUtil.getExtensionName(base64DecodedMultipartFile.getOriginalFilename());
                    // 文件类型
                    file = FileUtil.upload(base64DecodedMultipartFile, properties.getPath().getPath() + File.separator);
                    if (ObjectUtil.isNull(file)) {
                        throw new BadRequestException("上传失败");
                    }

                } catch (Exception e) {
                    e.printStackTrace();
                }

            }
        }



        if (userPortrait.getNickName().equals("微信用户")){
            if (ObjectUtil.isNotNull(user.getNickName())&&!user.getNickName().equals("微信用户")) {
                user.setNickName(user.getNickName());
            }else {
                user.setNickName(userPortrait.getNickName());
            }
        }else {
            user.setNickName(userPortrait.getNickName());
        }


        if (ObjectUtil.isNotNull(userPortrait.getAvatarUrl())) {
            if (userPortrait.getIsUrl()==0){
                user.setAvatarUrl("https://www.ciaojian.com/img/file/" + file.getName());
            }else {
                user.setAvatarUrl(userPortrait.getAvatarUrl());
            }
        }else {
            user.setAvatarUrl("https://www.ciaojian.com/img/file/1.png");
        }
        userMapper.updateById(user);
        return Result.ok(user);
    }

    @ApiModelProperty("获取用户信息")
    @GetMapping("/userByOpenId")
    public Result userByOpenId(@RequestParam String openId,@RequestParam(name = "storeType",required = false)String storeType) {


        QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
        userQueryWrapper.eq("openid",openId);
        User user = userMapper.selectOne(userQueryWrapper);
        if (ObjectUtil.isNull(user)){
            return Result.error("无用户,请授权登录");
        }

        if (ObjectUtil.isNull(user.getTelphone())){
            return Result.error("请授权手机号");
        }
        String token = TokenUtil.makeToken(user.getOpenid());
        user.setToken(token);


        if (ObjectUtil.isNotNull(storeType)&&"metro".equals(storeType)){
            redisTemplate.opsForValue().set("metro::user::"+user.getId(), "metro",RedisUtil.getRemainSecondsOneDay(new Date()), TimeUnit.SECONDS);
        }

        return Result.ok(user);
    }

    @ApiModelProperty("设置剪发周期 (天)")
    @PostMapping("/upHairperiod")
    public Result upHairperiod(@RequestBody UserHairperiod userHairperiod) {
        QueryWrapper<UserHairperiod> userHairperiodQueryWrapper = new QueryWrapper<>();
        userHairperiodQueryWrapper.eq("user_id",userHairperiod.getUserId());
        UserHairperiod userHairperiodOld = userHairperiodMapper.selectOne(userHairperiodQueryWrapper);
        if (ObjectUtil.isNotNull(userHairperiodOld)){
            userHairperiodOld.setTimelag(userHairperiod.getTimelag());
            userHairperiodOld.setLastTime(new Date());
            userHairperiodOld.setStatus(0);
            userHairperiodMapper.updateById(userHairperiodOld);
        }else {
            userHairperiod.setLastTime(new Date());
            userHairperiod.setStatus(0);
            userHairperiodMapper.insert(userHairperiod);
        }
        return Result.ok();
    }

}